﻿using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Web;
using System.Web.SessionState;
using System.Web.Caching;

namespace Dng.TraficTracking
{

	public class TraficTrackingModule : IHttpModule, IRequiresSessionState
	{
		void context_PostRequestHandlerExecute(object sender, EventArgs e)
		{
			
			HttpRequest request = ((HttpApplication)sender).Request;
			string url = Global.Instance.CompactUrl(request);
			if (url.Length >= 1)
			{
				SPSecurity.RunWithElevatedPrivileges(delegate()

{

				SPWeb web = new SPSite(Global.Instance.SiteUrl).OpenWeb();
					//SPControl.GetContextWeb(HttpContext.Current);//new SPSite(Global.Instance.SiteUrl).OpenWeb();
				web.AllowUnsafeUpdates = true;
				SPList supportList = web.Lists[Global.Instance.TraficTrackingListName];

				SPListItem newItem = supportList.Items.Add();
				newItem["Title"] = url;
				newItem["Ip"] = request.UserHostAddress;
				newItem["Time"] = Global.Now.ToString();
				//AddItemElevated(web, newItem);
				//try
				//{
					newItem.UpdateOverwriteVersion();
				//}
				//catch (Exception ex)
				//{
				//  HttpContext.Current.Application.Remove(url);
				//}

				if (HttpContext.Current.Application[url] != null)
				{
					newItem = (SPListItem)HttpContext.Current.Application[url];
					try
					{
						newItem["Visited"] = Convert.ToInt32(newItem["Visited"].ToString()) + 1;
						newItem.UpdateOverwriteVersion();
						HttpContext.Current.Application[url] = newItem;
					}
					catch
					{
						HttpContext.Current.Application.Remove(url);
					}
				}
				else
				{
					supportList = web.Lists[Global.Instance.TracficTrackingSummaryListName];
					string query = "<Where><Eq><FieldRef Name=\"Title\" /><Value Type=\"Text\">" + url + "</Value></Eq></Where>";
					SPQuery spquery = new SPQuery
					{
						Query = query
					};
					SPListItemCollection lists = supportList.GetItems(spquery);
					if (lists.Count < 1)
					{
						newItem = supportList.Items.Add();
						newItem["Title"] = url;
						newItem["Visited"] = 1;
						try
						{
							newItem.UpdateOverwriteVersion();
						}
						catch (Exception ex)
						{
							HttpContext.Current.Application.Remove(url);
						}
					}
					else
					{
						newItem = lists[0];
						newItem["Visited"] = Convert.ToInt32(newItem["Visited"].ToString()) + 1;
						try
						{
							newItem.UpdateOverwriteVersion();
						}
						catch (Exception ex)
						{
							HttpContext.Current.Application.Remove(url);
						}
					}
					HttpContext.Current.Application.Add(url, newItem);
				}
				if (!this.Counted)
				{
					if (HttpContext.Current.Application["HitCounter"] == null)
					{
						HttpContext.Current.Application["HitCounter"] = supportList.ItemCount;
					}
					else
					{
						HttpContext.Current.Application["HitCounter"] = ((int)HttpContext.Current.Application["HitCounter"]) + 1;
					}
					supportList = web.Lists[Global.Instance.VisitTrackingListName];
					newItem = supportList.Items.Add();
					newItem["Title"] = request.UserHostAddress;
					newItem["Time"] = Global.Now.ToString();
					try
					{
						newItem.UpdateOverwriteVersion();
					}
					catch (Exception ex)
					{
						HttpContext.Current.Application.Remove(url);
					}
					if (HttpContext.Current.Application["Counter"] == null)
					{
						HttpContext.Current.Application["Counter"] = supportList.ItemCount;
					}
					else
					{
						HttpContext.Current.Application["Counter"] = ((int)HttpContext.Current.Application["Counter"]) + 1;
					}
					HttpContext.Current.Cache.Insert(request.UserHostAddress, true, null, DateTime.Now.AddMinutes(Global.Instance.RefreshRate), Cache.NoSlidingExpiration);
				}

				web.AllowUnsafeUpdates = false;
});
			}
		}

		public void Dispose()
		{
		}

		public void Init(HttpApplication context)
		{

			context.PostRequestHandlerExecute += new EventHandler(context_PostRequestHandlerExecute);
			//context.BeginRequest += new EventHandler(context_BeginRequest);
			//context.PreSendRequestContent += new EventHandler(context_PreSendRequestContent);
		}

		//void context_PostRequestHandlerExecute(object sender, EventArgs e)
		//{
		//  throw new NotImplementedException();
		//}

		//void context_PreSendRequestContent(object sender, EventArgs e)
		//{
		//  throw new NotImplementedException();
		//}

		//void context_BeginRequest(object sender, EventArgs e)
		//{
		//  throw new NotImplementedException();
		//}

		public bool Counted
		{
			get
			{
				bool result = false;
				if (HttpContext.Current.Cache[HttpContext.Current.Request.UserHostAddress] != null)
				{
					result = true;
				}
				return result;
			}
		}

		public static void AddItemElevated(Guid siteID, SPListItem item, SPList list)
		{
			SPWeb web = SPControl.GetContextWeb(HttpContext.Current);
			SPList myList = web.Lists[Global.Instance.TraficTrackingListName];
			SPWeb myWeb = myList.ParentWeb;
			//myList.ParentWeb.Site.ID
			SPSecurity.RunWithElevatedPrivileges(delegate()
			{
				using (SPSite eleSite = new SPSite(web.Site.ID))
				{
					using (SPWeb eleWeb = eleSite.OpenWeb(myWeb.ID))
					{
						eleWeb.AllowUnsafeUpdates = true;
						SPList eleList = eleWeb.Lists[myList.Title];
						SPListItem itemToAdd = list.Items.Add();
						itemToAdd = item;
						itemToAdd.Update();
						eleWeb.AllowUnsafeUpdates = false;
					}
				}
			});
		}

		public static void AddItemElevated(SPWeb web, SPListItem item)
		{
			//SPWeb web = SPControl.GetContextWeb(HttpContext.Current);
			SPList myList = web.Lists[Global.Instance.TraficTrackingListName];
			SPWeb myWeb = myList.ParentWeb;
			//myList.ParentWeb.Site.ID
			SPSecurity.RunWithElevatedPrivileges(delegate()
			{
				using (SPSite eleSite = new SPSite(web.Site.ID))
				{
					using (SPWeb eleWeb = eleSite.OpenWeb(myWeb.ID))
					{
						eleWeb.AllowUnsafeUpdates = true;
						SPList eleList = eleWeb.Lists[myList.Title];
						SPListItem itemToAdd = myList.Items.Add();
						itemToAdd = item;
						itemToAdd.Update();
						eleWeb.AllowUnsafeUpdates = false;
					}
				}
			});
		}
		//public Hashtable Url
		//{
		//  get
		//  {
		//    if (HttpContext.Current.Session["Url"] == null)
		//    {
		//      Hashtable hashtable = new Hashtable();
		//      this.Url = hashtable;
		//      return hashtable;
		//    }
		//    return (Hashtable)HttpContext.Current.Session["Url"];
		//  }
		//  set
		//  {
		//    HttpContext.Current.Session["Url"] = value;
		//  }
		//}
	}
}